package vfs.service;

import java.util.Iterator;
import vfs.filter.VFSFilter;
import vfs.obj.entity.VFSNode;
import vfs.obj.entity.VFSNodeType;

/**
 *
 * @author Matthew Eavenson <durandal@uga.edu>
 * 
 */
public interface VFSNodeService {
    
    /**
     * Returns the path of a given node as a String.
     * 
     * @param node the node whose path is requested
     * @return the path of the node, if it exists, as a String, null otherwise
     */
    String getPath(VFSNode node);
    
    /**
     * Returns the type of the given node.
     * 
     * @param node the node whose type is requested
     * @return the node type if the node is not a folder, null otherwise
     */
    VFSNodeType getType(VFSNode node);
    
    /**
     * Returns an iterator over nodes, given a filter.
     * 
     * @param filter the filter over the node query
     * @return an iterator over any nodes that fit the given filter
     */
    Iterator<VFSNode> getNodes(VFSFilter filter);
    
    /**
     * Returns an iterator over nodes, given a node type and optional filter.
     * 
     * @param nodeType the type of the given nodes
     * @param filter an optional filter over the given nodes
     * @return an iterator over any nodes that have the given type and fit the optional filter
     */
    Iterator<VFSNode> getNodes(VFSNodeType nodeType, VFSFilter filter);
    
    /**
     * Returns a node, given the user performing the request, and
     * a directory path.
     * 
     * @param directory the directory path of the requested node
     * @return the node at the given directory path if it exists, null otherwise
     */
    VFSNode getNode(String directory);
    
    /**
     * Returns a node, given the user performing the request, and
     * a directory path relative to a working directory.
     * 
     * @param workingDir the current working directory
     * @param directory the directory path of the requested node relative to the working directory
     * @return the node at the given location if it exists, null otherwise
     */
    VFSNode getNode(VFSNode workingDir, String directory);
    
    /**
     * Returns whether a node exists within the system on a particular path, 
     * relative to the user's home directory.  If the path starts with "/"
     * the node is queried relative to the root node.
     * 
     * @param pathStr a String representing path information relative to the working directory
     * @return true if the node exists, false otherwise
     */
    boolean exists(String pathStr);
    
    /**
     * Returns whether a node exists within the system on a particular path, 
     * relative to a given working directory.  If the path starts with "/"
     * the node is queried relative to the root node.
     * 
     * @param workingDir the current working directory
     * @param pathStr a String representing path information relative to the working directory
     * @return true if the node exists, false otherwise
     */
    boolean exists(VFSNode workingDir, String pathStr);
    
    /**
     * Returns whether a node is the parent of any child nodes.
     * 
     * @param node the node to query for child nodes
     * @return true if the node has child nodes, false otherwise
     */
    boolean hasChildren(VFSNode node);
    
    /**
     * Creates a new virtual node, given its properties.
     * This method supports recursive creation when given a node name with slashes in it.
     * For example providing "folder1/folder2/folder3" as the node name will create
     * folder1 under the given parent, folder2 under folder1, and folder3 under folder2.
     * 
     * @param workingDir the id of the current working directory
     * @param name the new node's name (may contain slashes for recursive creation)
     * @param access the new node's public access level (ex. "read", "write", "none")
     * @param location the new node's reference to an outside source
     * @param nodeType a node type in the system
     * @return a newly created node
     */
    VFSNode create(VFSNode workingDir, String name, String access, String location, VFSNodeType nodeType);
    
    /**
     * Recursively creates a new virtual node, given its properties and path relative to the user's home directory.  
     * If the path starts with "/" the node is queried relative to the root node.
     * 
     * @param pathStr the new node's path
     * @param access the new node's public access level (ex. "read", "write", "none")
     * @param location the new node's reference to an outside source
     * @param nodeType a node type in the system
     * @return a newly created node
     */
    VFSNode create(String pathStr, String access, String location, VFSNodeType nodeType);
    
    /**
     * Removes a node from the system given a path. This method is not recursive, and will not 
     * remove directories. For that functionality, try remove(VFSUser user, String path, boolean recursive).
     * This method assumes that the path will be absolute.  If given a relative path, it will resolve it
     * relative to the root node.
     * 
     * @param path the location of the node to be removed
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(String path);
    
    /**
     * Removes a node from the system given a path. This method will remove directories if the recursive 
     * flag is set to true.  This method assumes that the path will be absolute.  If given a relative path, 
     * it will resolve it relative to the root node.
     * 
     * @param path the location of the node to be removed
     * @param recursive indicates whether this removal should be recursive (e.g. remove all subnodes)
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(String path, boolean recursive);
    
    /**
     * Removes a node from the system. This method is not recursive, and will not remove directories.
     * For that functionality, try remove(VFSUser user, VFSNode node, boolean recursive).
     * 
     * @param node the node to be removed
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(VFSNode node);
    
    /**
     * Removes a node from the system. This method will remove directories if the recursive flag is set to true.
     * 
     * @param node the node to be removed
     * @param recursive indicates whether this removal should be recursive (e.g. remove all subnodes)
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(VFSNode node, boolean recursive);
    
    /**
     * Removes a node from the system, given a working directory and optional path information. This 
     * method is not recursive, and will not remove directories.
     * For that functionality, try remove(VFSUser user, VFSNode workingDir, String pathStr, boolean recursive).
     * 
     * @param workingDir the current working directory
     * @param pathStr an optional String representing path information relative to the working directory
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(VFSNode workingDir, String pathStr);
    
    /**
     * Removes a node from the system, give its id, and optional path information. This method will remove
     * directories if the recursive flag is set to true.
     * 
     * @param workingDir the id of the current working directory
     * @param pathStr an optional String representing path information relative to the starting node
     * @param recursive indicates whether this removal should be recursive (e.g. remove all subnodes)
     * @return true if the node was removed successfully, false otherwise
     */
    boolean remove(VFSNode workingDir, String pathStr, boolean recursive);
    
    /**
     * Returns an iterator of immediate children of the optional path, relative to the
     * given working directory.  If path information is not given, the working directory's
     * children are returned.
     * 
     * @param workingDir the id of the current working directory
     * @param pathStr an optional String representing path information relative to the starting node
     * @return an iterator of nodes
     */
    Iterator<VFSNode> list(VFSNode workingDir, String pathStr);
    
    /**
     * Renames a given node.
     * 
     * @param node the node to be renamed
     * @param name the new name of the node
     * @return true if the node was renamed successfully, false otherwise
     */
    boolean rename(VFSNode node, String name);
    
    /**
     * Moves a node from a given source path to a given destination path.  Does
     * not create the destination path if it does not already exist.
     * 
     * @param workingDir the current working directory
     * @param srcPathStr the source path
     * @param destPathStr the destination path
     * @return true if the move was successful, false otherwise
     */
    boolean move(VFSNode workingDir, String srcPathStr, String destPathStr);
    
    /**
     * Moves a node under another node. 
     * 
     * @param srcId the source node
     * @param destId the destination node
     * @return true if the move was successful, false otherwise
     */
    boolean move(VFSNode src, VFSNode dest);
    
}
